# -*- coding: utf-8 -*-
import sys
import os
from PySide import QtGui
from PySide import QtCore
import res


class TextEdit(QtGui.QTextEdit):
    def __init__(self, parent=None):
        super(TextEdit, self).__init__(parent)
        self.filename = u''

    def set_filename(self, filename=u''):
        self.filename = filename
        self.document().setModified(False)

    def canInsertFromMimeData(self, source):
        if source.hasImage():
            return True
        else:
            return super(TextEdit, self).canInsertFromMimeData(source)

    def insertFromMimeData(self, source):
        if source.hasImage():
            image = source.imageData()
            buf = QtCore.QByteArray()
            io = QtCore.QBuffer(buf)
            image.save(io, 'png', 0)
            html_src = u'<img src="data:image/png;base64,%s">' % buf.toBase64().data()
            self.textCursor().insertHtml(html_src)
        else:
            super(TextEdit, self).insertFromMimeData(source)

    def merge_format(self, fmt):
        self.mergeCurrentCharFormat(fmt)


class Center(QtGui.QWidget):
    def __init__(self, parent=None):
        super(Center, self).__init__(parent)

        split = QtGui.QSplitter(self)
        self.tree = QtGui.QTreeView(split)
        self.tab = QtGui.QTabWidget(split)
        self.tab.setTabsClosable(True)
        split.setStretchFactor(1, 1)

        self.model = QtGui.QFileSystemModel()
        self.model.setNameFilters([u'*.html', u'*.txt'])
        self.model.setNameFilterDisables(False)
        self.tree.setModel(self.model)

        for i in range(1, self.model.columnCount()):
            self.tree.hideColumn(i)

        layout = QtGui.QHBoxLayout()
        layout.addWidget(split)
        self.setLayout(layout)


class Window(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.init_data()
        self.init_ui()

    def init_data(self):
        self.default_font_family = u'新宋体'
        self.default_font_size = 12
        self.default_work_path = u'.'
        self.current_model_index = None
        self.painter_fmt = None
        self.get_config_data()

    def get_config_data(self):
        cd = os.path.dirname(sys.argv[0])
        self.config_file_path = os.path.join(cd, u'setting.ini')
        if not os.path.exists(self.config_file_path):
            self.default_work_path = u'.'
            return
        with open(self.config_file_path, 'r') as fr:
            self.default_work_path = fr.readlines()[0].strip().decode('utf-8')

    def set_config_data(self):
        with open(self.config_file_path, 'w') as fw:
            fw.write(self.default_work_path.encode('utf-8'))

    def init_ui(self):
        self.setWindowIcon(QtGui.QIcon(u':/image/title.png'))
        self.setWindowTitle(u'富文本编辑器 --- ' + os.path.abspath(self.default_work_path))
        self.center = Center(self)
        self.center.model.setRootPath(self.default_work_path)
        self.center.tree.setRootIndex(self.center.model.index(self.default_work_path))
        self.center.tab.tabCloseRequested[int].connect(self.tab_close_requested_slot)
        self.center.tab.currentChanged[int].connect(self.tab_current_changed_slot)
        self.center.tree.doubleClicked[QtCore.QModelIndex].connect(self.double_clicked_tree_slot)
        self.center.tree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.center.tree.customContextMenuRequested[QtCore.QPoint].connect(self.tree_custom_context_menu_requested_slot)
        self.setCentralWidget(self.center)
        self.saved_ico = QtGui.QIcon(u':/image/saved.png')
        self.unsaved_ico = QtGui.QIcon(u':/image/unsaved.png')

        menubar = self.menuBar()

        # 文件菜单
        file_menu = menubar.addMenu(u'文件(&F)')
        file_toolbar = self.addToolBar(u'文件')

        self.file_new_action = QtGui.QAction(QtGui.QIcon(u':/image/filenew.png'), u'新建文件(&N)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtGui.QKeySequence.New, triggered=self.file_new_slot)
        file_menu.addAction(self.file_new_action)
        file_toolbar.addAction(self.file_new_action)

        self.file_open_action = QtGui.QAction(QtGui.QIcon(u':/image/fileopen.png'), u'打开文件(&O)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtGui.QKeySequence.Open, triggered=self.file_open_slot)
        file_menu.addAction(self.file_open_action)
        file_toolbar.addAction(self.file_open_action)

        self.file_add_folder_action = QtGui.QAction(QtGui.QIcon(u':/image/fileaddfolder.png'), u'选择工程目录', self, priority=QtGui.QAction.LowPriority,
            triggered=self.file_add_folder_slot)
        file_menu.addAction(self.file_add_folder_action)

        self.file_save_action = QtGui.QAction(QtGui.QIcon(u':/image/filesave.png'), u'保存文件(&S)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtGui.QKeySequence.Save, triggered=self.file_save_slot)
        file_menu.addAction(self.file_save_action)
        file_toolbar.addAction(self.file_save_action)

        self.file_saveas_action = QtGui.QAction(QtGui.QIcon(u':/image/filesave.png'), u'另存为...(&A)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtCore.Qt.CTRL + QtCore.Qt.SHIFT + QtCore.Qt.Key_S, triggered=self.file_saveas_slot)
        file_menu.addAction(self.file_saveas_action)

        self.file_exportpdf_action = QtGui.QAction(QtGui.QIcon(u':/image/filepdf.png'), u'导出PDF文件', self, priority=QtGui.QAction.LowPriority,
            triggered=self.file_exportpdf_slot)
        file_menu.addAction(self.file_exportpdf_action)

        file_menu.addSeparator()

        self.file_close_action = QtGui.QAction(QtGui.QIcon(u':/image/fileclose.png'), u'关闭文件(&C)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtCore.Qt.CTRL + QtCore.Qt.Key_W, triggered=self.file_close_slot)
        file_menu.addAction(self.file_close_action)

        self.file_exit_action = QtGui.QAction(QtGui.QIcon(u':/image/fileexit.png'), u'退出(&S)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtCore.Qt.CTRL + QtCore.Qt.Key_X, triggered=self.file_exit_slot)
        file_menu.addAction(self.file_exit_action)

        # 格式菜单
        fmt_menu = menubar.addMenu(u'格式(&O)')
        fmt_toolbar = self.addToolBar(u'格式')

        self.fmt_bold_action = QtGui.QAction(QtGui.QIcon(u':/image/textbold.png'), u'加粗(&B)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtCore.Qt.CTRL + QtCore.Qt.Key_B, triggered=self.fmt_bold_slot, checkable=True)
        font = QtGui.QFont()
        font.setBold(True)
        self.fmt_bold_action.setFont(font)
        fmt_menu.addAction(self.fmt_bold_action)
        fmt_toolbar.addAction(self.fmt_bold_action)

        self.fmt_italic_action = QtGui.QAction(QtGui.QIcon(u':/image/textitalic.png'), u'斜体(&I)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtCore.Qt.CTRL + QtCore.Qt.Key_I, triggered=self.fmt_italic_slot, checkable=True)
        font = QtGui.QFont()
        font.setItalic(True)
        self.fmt_italic_action.setFont(font)
        fmt_menu.addAction(self.fmt_italic_action)
        fmt_toolbar.addAction(self.fmt_italic_action)

        self.fmt_underline_action = QtGui.QAction(QtGui.QIcon(u':/image/textunder.png'), u'下划线(&U)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtCore.Qt.CTRL + QtCore.Qt.Key_U, triggered=self.fmt_underline_slot, checkable=True)
        font = QtGui.QFont()
        font.setUnderline(True)
        self.fmt_underline_action.setFont(font)
        fmt_menu.addAction(self.fmt_underline_action)
        fmt_toolbar.addAction(self.fmt_underline_action)

        self.fmt_strikeout_action = QtGui.QAction(QtGui.QIcon(u':/image/textstrikeout.png'), u'删除线(&D)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtCore.Qt.CTRL + QtCore.Qt.Key_D, triggered=self.fmt_strikeout_slot, checkable=True)
        font = QtGui.QFont()
        font.setStrikeOut(True)
        self.fmt_strikeout_action.setFont(font)
        fmt_menu.addAction(self.fmt_strikeout_action)
        fmt_toolbar.addAction(self.fmt_strikeout_action)

        fmt_menu.addSeparator()

        alig_toolbar = self.addToolBar(u'对齐')

        grp = QtGui.QActionGroup(self)
        grp.triggered[QtGui.QAction].connect(self.text_align_slot)

        self.alig_justify_action = QtGui.QAction(QtGui.QIcon(u':/image/aligjustify.png'), u'自动', grp, priority=QtGui.QAction.LowPriority,
            checkable=True)
        fmt_menu.addAction(self.alig_justify_action)
        alig_toolbar.addAction(self.alig_justify_action)

        self.alig_left_action = QtGui.QAction(QtGui.QIcon(u':/image/aligleft.png'), u'左对齐', grp, priority=QtGui.QAction.LowPriority,
            checkable=True)
        fmt_menu.addAction(self.alig_left_action)
        alig_toolbar.addAction(self.alig_left_action)

        self.alig_center_action = QtGui.QAction(QtGui.QIcon(u':/image/aligcenter.png'), u'居中', grp, priority=QtGui.QAction.LowPriority,
            checkable=True)
        fmt_menu.addAction(self.alig_center_action)
        alig_toolbar.addAction(self.alig_center_action)

        self.alig_right_action = QtGui.QAction(QtGui.QIcon(u':/image/aligright.png'), u'右对齐', grp, priority=QtGui.QAction.LowPriority,
            checkable=True)
        fmt_menu.addAction(self.alig_right_action)
        alig_toolbar.addAction(self.alig_right_action)

        # 帮助菜单
        help_menu = menubar.addMenu(u'帮助(&H)')

        self.help_aboutqt_action = QtGui.QAction(QtGui.QIcon(u':/image/aboutqt.png'), u'关于QT(&Q)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtCore.Qt.CTRL + QtCore.Qt.Key_Q, triggered=QtGui.QApplication.instance().aboutQt)
        help_menu.addAction(self.help_aboutqt_action)

        self.help_about_action = QtGui.QAction(QtGui.QIcon(u':/image/about.png'), u'关于(&A)', self, priority=QtGui.QAction.LowPriority,
            shortcut=QtCore.Qt.CTRL + QtCore.Qt.Key_A, triggered=self.help_about_slot)
        help_menu.addAction(self.help_about_action)

        # 字体颜色工具栏
        color_toolbar = self.addToolBar(u'颜色')
        self.foreground_color_action = QtGui.QAction(QtGui.QIcon(u':/image/textcolor.png'), u'前景色', self, triggered=self.foreground_color_slot)
        color_toolbar.addAction(self.foreground_color_action)

        self.background_color_action = QtGui.QAction(QtGui.QIcon(u':/image/bgcolor.png'), u'背景色', self, triggered=self.background_color_slot)
        color_toolbar.addAction(self.background_color_action)

        # 格式刷
        self.fmt_painter_action = QtGui.QAction(QtGui.QIcon(u':/image/fontfmt.png'), u'格式刷',
            self, shortcut=QtCore.Qt.CTRL + QtCore.Qt.Key_E, checkable=True, triggered=self.fmt_painter_slot)
        color_toolbar.addAction(self.fmt_painter_action)

        font_toolbar = self.addToolBar(u'字体')

        self.font_combobox = QtGui.QFontComboBox()
        self.font_combobox.activated[unicode].connect(self.font_family_slot)
        self.font_combobox.setEditable(False)
        self.font_combobox.setCurrentIndex(self.font_combobox.findText(self.default_font_family))
        font_toolbar.addWidget(self.font_combobox)

        font_toolbar.addSeparator()

        self.font_size = QtGui.QComboBox()
        self.font_size.activated[unicode].connect(self.font_size_slot)
        self.font_size.setEditable(False)
        self.font_size.addItems(map(lambda x: unicode(x), QtGui.QFontDatabase().standardSizes()))
        self.font_size.setCurrentIndex(self.font_size.findText(u'%d' % self.default_font_size))
        font_toolbar.addWidget(self.font_size)

        # 左栏右键菜单
        self.tree_open_action = QtGui.QAction(u'打开文件', self, priority=QtGui.QAction.LowPriority,
            triggered=self.tree_open_slot)
        self.tree_rm_file_action = QtGui.QAction(u'删除', self, priority=QtGui.QAction.LowPriority,
            triggered=self.tree_rm_file_slot)
        self.tree_new_file_action = QtGui.QAction(u'新建文件', self, priority=QtGui.QAction.LowPriority,
            triggered=self.tree_new_file_slot)
        self.tree_new_dir_action = QtGui.QAction(u'新建文件夹', self, priority=QtGui.QAction.LowPriority,
            triggered=self.tree_new_dir_slot)
        self.tree_rm_dir_action = QtGui.QAction(u'删除文件夹', self, priority=QtGui.QAction.LowPriority,
            triggered=self.tree_rm_dir_slot)

    def set_aligment(self, alig):
        if alig & QtCore.Qt.AlignLeft:
            self.alig_left_action.setChecked(True)
        elif alig & QtCore.Qt.AlignHCenter:
            self.alig_center_action.setChecked(True)
        elif alig & QtCore.Qt.AlignRight:
            self.alig_right_action.setChecked(True)
        elif alig & QtCore.Qt.AlignJustify:
            self.alig_justify_action.setChecked(True)
        else:
            return

    def tree_custom_context_menu_requested_slot(self, pos):
        self.current_model_index = self.center.tree.indexAt(pos)
        path = self.center.model.filePath(self.current_model_index)
        menu = QtGui.QMenu()
        if not path:
            menu.addAction(self.file_add_folder_action)
            menu.addAction(self.tree_new_file_action)
            menu.addAction(self.tree_new_dir_action)
        elif os.path.isfile(path):
            menu.addAction(self.tree_open_action)
            menu.addAction(self.tree_rm_file_action)
        elif os.path.isdir(path):
            menu.addAction(self.tree_new_file_action)
            menu.addAction(self.tree_new_dir_action)
            menu.addAction(self.tree_rm_dir_action)
        else:
            return
        menu.exec_(QtGui.QCursor.pos())


    def tree_open_slot(self):
        filepath = self.center.model.filePath(self.current_model_index)
        self.open_file(filepath)

    def tree_rm_file_slot(self):
        if not self.center.model.remove(self.current_model_index):
            QtGui.QMessageBox.warning(self, u'错误', u'删除文件失败')

    def tree_new_file_slot(self):
        filename, isOK = QtGui.QInputDialog.getText(self, u'新建文件', u'输入文件名')
        if not isOK:
            return
        if not filename:
            return
        if not (filename.endswith(u'html') or filename.endswith(u'txt')):
            filename += u'.html'

        if self.current_model_index.isValid():
            dir_path = self.center.model.filePath(self.current_model_index)
        else:
            dir_path = self.center.model.rootPath()

        file_full_path = os.path.join(dir_path, filename)
        fw = open(file_full_path, 'w')
        fw.write(file_full_path.encode('utf-8'))
        fw.close()

    def tree_new_dir_slot(self):
        dirname, isOK = QtGui.QInputDialog.getText(self, u'新建文件夹', u'输入文件夹名')
        if not isOK:
            return

        if self.current_model_index.isValid():
            self.center.model.mkdir(self.current_model_index, dirname)
        else:
            self.center.model.mkdir(self.center.model.index(self.center.model.rootPath()), dirname)

    def tree_rm_dir_slot(self):
        if not self.center.model.rmdir(self.current_model_index):
            QtGui.QMessageBox.warning(self, u'错误', u'文件夹不为空')

    def cursor_position_changed_slot(self):
        edit = self.center.tab.currentWidget()
        if not edit:
            return True
        self.set_aligment(edit.alignment())

    def tab_close_requested_slot(self, index):
        self.center.tab.setCurrentIndex(index)
        self.file_close_slot()

    def tab_current_changed_slot(self, index):
        pass

    def double_clicked_tree_slot(self, index):
        file_path = self.center.model.filePath(index)
        if os.path.isfile(file_path):
            self.open_file(file_path)

    def font_changed(self, font):
        self.fmt_bold_action.setChecked(font.bold())
        self.fmt_italic_action.setChecked(font.italic())
        self.fmt_underline_action.setChecked(font.underline())
        self.fmt_strikeout_action.setChecked(font.strikeOut())

        self.font_combobox.setCurrentIndex(self.font_combobox.findText(font.family()))
        self.font_size.setCurrentIndex(self.font_size.findText(u'%d' % font.pointSize()))

    def current_char_format_changed_slot(self, fmt):
        self.font_changed(fmt.font())

    def document_modification_changed_slot(self, modified):
        index = self.center.tab.currentIndex()
        if modified:
            self.center.tab.setTabIcon(index, self.unsaved_ico)
        else:
            self.center.tab.setTabIcon(index, self.saved_ico)

    def create_edit_and_slot(self):
        edit = TextEdit()
        edit.cursorPositionChanged.connect(self.cursor_position_changed_slot)
        edit.currentCharFormatChanged[QtGui.QTextCharFormat].connect(
            self.current_char_format_changed_slot)
        edit.selectionChanged.connect(self.selection_changed_slot)
        edit.document().modificationChanged[bool].connect(
            self.document_modification_changed_slot)
        font = QtGui.QFont(self.default_font_family, self.default_font_size)
        edit.setFont(font)
        self.set_aligment(edit.alignment())
        self.font_changed(edit.font())

        return edit

    def selection_changed_slot(self):
        if not self.fmt_painter_action.isChecked():
            return
        if not self.painter_fmt:
            return
        edit = self.center.tab.currentWidget()
        edit.merge_format(self.painter_fmt)

    def file_new_slot(self):
        edit = self.create_edit_and_slot()
        self.center.tab.addTab(edit, self.saved_ico, u'未命名.html')
        self.center.tab.setCurrentWidget(edit)

    def file_add_folder_slot(self):
        directory = QtGui.QFileDialog.getExistingDirectory(self,
            u'选择目录', u'', QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog)
        if not directory:
            return

        self.center.model.setRootPath(directory)
        self.center.tree.setRootIndex(self.center.model.index(directory))
        self.default_work_path = directory
        self.setWindowTitle(u'富文本编辑器 --- ' + os.path.abspath(self.default_work_path))

    def open_file(self, filename):
        # 遍历已打开文件路径相同直接切换tab
        count = self.center.tab.count()
        for i in range(count):
            edit = self.center.tab.widget(i)
            if edit.filename == filename:
                self.center.tab.setCurrentWidget(edit)
                return

        with open(filename, 'r') as fobj:
            edit = self.create_edit_and_slot()
            edit.set_filename(filename)
            self.center.tab.addTab(edit, self.saved_ico, os.path.basename(edit.filename))
            self.center.tab.setCurrentWidget(edit)
            edit.setText(fobj.read().decode('utf-8'))

    def file_open_slot(self):
        filename, _ = QtGui.QFileDialog.getOpenFileName(self,
            u'打开文件', u'', u'网页文件(*.html);;文本文件(*.txt)',
            None, QtGui.QFileDialog.DontUseNativeDialog)
        if not filename:
            return
        self.open_file(filename)

    def savefile(self, filename):
        index = self.center.tab.currentIndex()
        edit = self.center.tab.currentWidget()
        with open(filename, 'w') as fobj:
            if filename.endswith('html'):
                fobj.write(edit.toHtml().encode('utf-8'))
            elif filename.endswith('txt'):
                fobj.write(edit.toPlainText().encode('utf-8'))
            else:
                filename += '.html'
                fobj.write(edit.toHtml().encode('utf-8'))
            self.center.tab.setTabText(index, os.path.basename(filename))
            edit.set_filename(filename)
            return True
        return False

    def file_save_slot(self):
        edit = self.center.tab.currentWidget()
        if not edit:
            return True

        # 如果没有修改文件，不需要保存
        if not edit.document().isModified():
            return True

        filename = edit.filename
        if not filename:
            return self.file_saveas_slot()
        else:
            return self.savefile(filename)

    def file_saveas_slot(self):
        filename, _ = QtGui.QFileDialog.getSaveFileName(self,
            u'保存文件', u'', u'网页文件(*.html);;文本文件(*.txt)',
            None, QtGui.QFileDialog.DontUseNativeDialog)
        if filename:
            self.savefile(filename)
            return True
        return False

    def file_exportpdf_slot(self):
        filename, _ = QtGui.QFileDialog.getSaveFileName(self,
            u'导出PDF文件', u'', u'PDF文件(*.pdf)',
            None, QtGui.QFileDialog.DontUseNativeDialog)
        if not filename:
            return
        if not filename.endswith('pdf'):
            filename += '.pdf'
        edit = self.center.tab.currentWidget()
        printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
        printer.setOutputFileName(filename)
        printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
        edit.print_(printer)

    def file_close_slot(self):
        edit = self.center.tab.currentWidget()
        if not edit:
            return
        index = self.center.tab.currentIndex()
        if edit.document().isModified():
            # 弹出是否保存对话框
            ret = QtGui.QMessageBox.warning(self, u'保存文件',
                u'是否保存文件?',
                QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel)
            if ret == QtGui.QMessageBox.Save:
                if self.file_save_slot():
                    self.center.tab.removeTab(index)
            elif ret == QtGui.QMessageBox.Discard: # 不保存直接关闭
                self.center.tab.removeTab(index)
            else: # 不保存也不关闭
                pass
        else:
            self.center.tab.removeTab(index)

    def file_exit_slot(self):
        self.close()

    def fmt_bold_slot(self):
        checked = self.fmt_bold_action.isChecked()
        edit = self.center.tab.currentWidget()
        if not edit:
            return
        fmt = QtGui.QTextCharFormat()
        fmt.setFontWeight(checked and QtGui.QFont.Bold or QtGui.QFont.Normal)
        edit.merge_format(fmt)

    def fmt_italic_slot(self):
        checked = self.fmt_italic_action.isChecked()
        edit = self.center.tab.currentWidget()
        if not edit:
            return
        fmt = QtGui.QTextCharFormat()
        fmt.setFontItalic(checked)
        edit.merge_format(fmt)

    def fmt_underline_slot(self):
        checked = self.fmt_underline_action.isChecked()
        edit = self.center.tab.currentWidget()
        if not edit:
            return
        fmt = QtGui.QTextCharFormat()
        fmt.setFontUnderline(checked)
        edit.merge_format(fmt)

    def fmt_strikeout_slot(self):
        checked = self.fmt_strikeout_action.isChecked()
        edit = self.center.tab.currentWidget()
        if not edit:
            return
        fmt = QtGui.QTextCharFormat()
        fmt.setFontStrikeOut(checked)
        edit.merge_format(fmt)

    def text_align_slot(self, action):
        edit = self.center.tab.currentWidget()
        if not edit:
            return
        if action == self.alig_left_action:
            edit.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignAbsolute)
        elif action == self.alig_center_action:
            edit.setAlignment(QtCore.Qt.AlignHCenter)
        elif action == self.alig_right_action:
            edit.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignAbsolute)
        elif action == self.alig_justify_action:
            edit.setAlignment(QtCore.Qt.AlignJustify)
        else:
            pass

    def help_about_slot(self):
        QtGui.QMessageBox.about(self, u'关于本程序', u'富文本编辑器\n\n作者:\nzhangjia_86@126.com')

    def foreground_color_slot(self):
        edit = self.center.tab.currentWidget()
        if not edit:
            return
        current_color = edit.textColor()
        color = QtGui.QColorDialog.getColor(current_color, self, u'选择字体颜色')
        if not color.isValid():
            return

        fmt = QtGui.QTextCharFormat()
        fmt.setForeground(color)
        edit.merge_format(fmt)

    def background_color_slot(self):
        edit = self.center.tab.currentWidget()
        if not edit:
            return
        current_color = edit.textBackgroundColor()
        color = QtGui.QColorDialog.getColor(current_color, self, u'选择字体背景色')
        if not color.isValid():
            return

        fmt = QtGui.QTextCharFormat()
        fmt.setBackground(color)
        edit.merge_format(fmt)

    def font_family_slot(self, family):
        edit = self.center.tab.currentWidget()
        if not edit:
            return
        fmt = QtGui.QTextCharFormat()
        fmt.setFontFamily(family)
        edit.merge_format(fmt)

    def font_size_slot(self, size):
        edit = self.center.tab.currentWidget()
        if not edit:
            return
        fmt = QtGui.QTextCharFormat()
        fmt.setFontPointSize(int(size, 10))
        edit.merge_format(fmt)

    def can_close_all(self):
        count = self.center.tab.count()
        for i in range(count):
            edit = self.center.tab.widget(i)
            if edit.document().isModified():
                return False
        return True

    def closeEvent(self, event):
        self.set_config_data()
        if (self.can_close_all()):
            event.accept()
        else:
            ret = QtGui.QMessageBox.warning(self, u'结束程序',
                u'部分文件尚未保存，是否直接结束程序?',
                QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
            if ret == QtGui.QMessageBox.Yes:
                event.accept()
            else:
                event.ignore()

    def fmt_painter_slot(self):
        edit = self.center.tab.currentWidget()
        if not edit:
            return
        if self.fmt_painter_action.isChecked():
            self.painter_fmt = edit.currentCharFormat()
        else:
            self.painter_fmt = None

    def test_slot(self):
        print 'test...'

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    widget = Window()
    widget.showMaximized()
    sys.exit(app.exec_())
